import React, { useState, createRef } from 'react';
import throttle from '&helpers/throttle';

import styles from './styles.module.less';

class DragNode extends React.Component {
    constructor(props) {
        super(props);
        this.dragNode = createRef();
        this.diffX = 0;
        this.diffY = 0;
        this.originX = props.left;
        this.originY = props.top;
    }

    static defaultProps = {
        top: 0,
        left: 0
    };

    componentDidMount() {
        this.current = this.dragNode.current;
        this.parent = this.current.parentNode;
        this.current.style.top = `${this.originY - this.parent.getBoundingClientRect().top}px`;
        this.current.style.left = `${this.originX - this.parent.getBoundingClientRect().left}px`;
        this.current.addEventListener('mousedown', this, false);
    }

    handleEvent = (e) => {
        switch (e.type) {
            case 'mousedown':
                this._start(e);
                break;
            case 'mousemove':
                this._move(e);
                break;
            case 'mouseup':
                this._end(e);
                break;
        }
    };

    _start = () => {
        this.diffX = this.parent.getBoundingClientRect().left;
        this.diffY = this.parent.getBoundingClientRect().top;
        document.addEventListener('mousemove', this, false);
        document.addEventListener('mouseup', this, false);
    };

    _move = throttle((e) => {
        this.originX = e.pageX - this.diffX;
        this.originY = e.pageY - this.diffY;
        this.current.style.top = `${this.originY}px`;
        this.current.style.left = `${this.originX}px`;
    }, 30);

    _end = (e) => {
        document.removeEventListener('mousemove', this, false);
        document.removeEventListener('mouseup', this, false);
    };

    render() {
        const { children } = this.props;
        return (
            <div ref={ this.dragNode } className={ styles.dragNode }>
                { children }
            </div>
        );
    }
}

export default DragNode;